package overtime

import (
	"fmt"
	"gitee.com/baal1990/gitee.com/baal1990/cmd/server_attence/app/dao"
	"gitee.com/baal1990/gitee.com/baal1990/cmd/server_attence/app/entity"
	"gitee.com/baal1990/gitee.com/baal1990/cmd/server_attence/app/global"
	"gitee.com/baal1990/gitee.com/baal1990/pkg/db"
	"gitee.com/baal1990/gitee.com/baal1990/pkg/model"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
	"strconv"
	"strings"
	"time"
)

//********************************************
//Func  ：查询加班列表
//Method：GET
//Usage ：
//********************************************
func QueryOvertimeList(c *gin.Context) {
	requester := c.MustGet("USER").(*entity.Employee) //请求人

	pageSize, err1 := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
	if err1 != nil {
		global.Log.Error("QueryOvertimeList input param pagesize error:", zap.Any("error", err1))
		c.JSON(http.StatusOK, model.Fail("请求参数错误"))
		return
	}

	page, err2 := strconv.Atoi(c.DefaultQuery("page", "1"))
	if err2 != nil {
		global.Log.Error("QueryOvertimeList input param page error:", zap.Any("error", err2))
		c.JSON(http.StatusOK, model.Fail("请求参数错误"))
		return
	}

	//指定部门
	deptId, err := strconv.ParseInt(c.DefaultQuery("deptId", ""), 10, 64)
	if err != nil {
		deptId = 0
		global.Log.Info("QueryOvertimeList deptid is missing.")
	}

	//指定申请者
	applicantId, err := strconv.ParseInt(c.DefaultQuery("applicantId", ""), 10, 64)
	if err != nil {
		applicantId = 0
		global.Log.Info("QueryOvertimeList applicantId is missing.")
	}

	overtimeType := entity.EOvertimeType_Unknow
	status, err := strconv.Atoi(c.DefaultQuery("status", "0"))
	if err != nil {
		global.Log.Info("QueryOvertimeList input param status missing:", zap.Any("error", err))
	}

	startDate := c.DefaultQuery("startDate", "")
	endDate := c.DefaultQuery("endDate", "")

	if requester.Role == entity.EEmployeeRole_Outsourcing { //如果是员工，只能看自己了
		if applicantId != requester.Id && applicantId > 0 {
			//请求数据与请求者身份不匹配
			global.Log.Error("QueryOvertimeList employee requester has no auth:",
				zap.Any("applicantId", applicantId), zap.Any("requester", requester.Id))
			c.JSON(http.StatusOK, model.Fail("查询目标与请求者身份不匹配"))
			return
		}
	} else if requester.Role == entity.EEmployeeRole_DeptLeader {
		//非本部门的，不能查看
		if deptId <= 0 {
			deptId = requester.DeptId
		} else {
			if deptId != requester.DeptId {
				global.Log.Error("QueryOvertimeList leader requester has no auth for other dept:",
					zap.Any("Req deptId", deptId), zap.Any("requester deptId", requester.DeptId))
				c.JSON(http.StatusOK, model.Fail("查询请求者不能查询其它部门的数据"))
			}
		}
	} else if requester.Role == entity.EEmployeeRole_Hr {
		//查看所有外包员工.

	}

	total, list, err := dao.QueryOvertimeList(page, pageSize, overtimeType,
		status, startDate, endDate, applicantId, deptId)
	if err != nil {
		global.Log.Error("QueryOvertimeList failed.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("查询失败"))
	} else {

		type OvertimeList struct { //列表查询输出
			Total int64
			List  []*entity.OutputOvertimeInfo
		}

		employeeMap := dao.GetAllEmployeeMap()
		if employeeMap != nil {
			for _, overtime := range list {
				if overtime.ApproverId > 0 {
					employee, has := employeeMap[overtime.ApproverId]
					if has {
						overtime.ApproverName = employee.Name
					}
				}

				if overtime.ApplicantId > 0 {
					employee, has := employeeMap[overtime.ApplicantId]
					if has {
						overtime.ApplicantName = employee.Name
					}
				}
			}
		}

		output := &OvertimeList{
			Total: total,
		}

		for _, overtime := range list {
			info := &entity.OutputOvertimeInfo{
				Id:            strconv.FormatInt(overtime.Id, 10),
				ApplicantId:   strconv.FormatInt(overtime.ApplicantId, 10),
				ApproverId:    strconv.FormatInt(overtime.ApproverId, 10), //审批人ID
				DeptId:        strconv.FormatInt(overtime.DeptId, 10),     //部门ID
				Reason:        overtime.Reason,
				StartDate:     overtime.StartDate,
				EndDate:       overtime.EndDate,
				Duration:      overtime.Duration,
				CreateAt:      overtime.CreateAt,
				ApproveAt:     overtime.ApproveAt,
				Type:          overtime.Type,          //类型 0、不限、1工作日、2周末、3法定假日、4其它
				Status:        overtime.Status,        //0:draft，1：send；2：delete；3:recall，4:refuse
				Note:          overtime.Note,          //备注
				ApplicantName: overtime.ApplicantName, //申请人姓名
				ApproverName:  overtime.ApproverName,  //审批人姓名
				DeptName:      overtime.DeptName,      //部门名称	employee.id
				DurationDay:   overtime.DurationDay,   // 时长（天，0.5起跳）
				ApplyType:     overtime.ApplyType,     //类型 0、不限、1工作日、2周末、3法定假日、4其它
				ApplyStatus:   overtime.ApplyStatus,   //0:draft，1：send；2：delete；3:recall，4:refuse
			}
			output.List = append(output.List, info)
		}
		c.JSON(http.StatusOK, model.SuccessObject("操作成功", output))
		global.Log.Info("QueryOvertimeList success.", zap.Any("overtime list", output))
	}
}

//********************************************
//Func  ：查询指定加班申请详情
//Method：GET
//Usage ：
//********************************************
func QueryOvertimeDetail(c *gin.Context) {
	requester := c.MustGet("USER").(*entity.Employee) //请求人
	overtimeId, err := strconv.ParseInt(c.DefaultQuery("overtimeId", ""), 10, 64)
	if err != nil {
		global.Log.Error("QueryOvertimeDetail overtimeId is lost.")
		c.JSON(http.StatusOK, model.Fail("未指明加班ID"))
		return
	}
	if overtimeId <= 0 {
		global.Log.Error("QueryOvertimeDetail deptid is lost.")
		c.JSON(http.StatusOK, model.Fail("未指明查询ID"))
		return
	}

	overtimeInfo, err := dao.QueryOvertimeInfo(overtimeId)
	if err != nil {
		global.Log.Error("QueryOvertimeDetail failed.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("查询部门详情失败"))
		return
	}
	if overtimeInfo == nil {
		c.JSON(http.StatusOK, model.Fail("未找到指定申请"))
		global.Log.Info("QueryOvertimeDetail dept is nil.")
		return
	}

	if requester.Role == entity.EEmployeeRole_Outsourcing { //如果是员工，只能看自己了
		if requester.Id != overtimeInfo.ApplicantId {
			//请求数据与请求者身份不匹配
			global.Log.Error("QueryOvertimeDetail employee requester has no auth:",
				zap.Any("applicantId", overtimeInfo.ApplicantId), zap.Any("requester", requester.Id))
			c.JSON(http.StatusOK, model.Fail("查询目标与请求者身份不匹配"))
			return
		}
	}
	var output entity.OutputOvertimeInfo
	output.Id = strconv.FormatInt(overtimeInfo.Id, 10)
	output.ApplicantId = strconv.FormatInt(overtimeInfo.ApplicantId, 10)
	output.ApproverId = strconv.FormatInt(overtimeInfo.ApproverId, 10) //审批人ID
	output.DeptId = strconv.FormatInt(overtimeInfo.DeptId, 10)         //部门ID
	output.Reason = overtimeInfo.Reason
	output.StartDate = overtimeInfo.StartDate
	output.EndDate = overtimeInfo.EndDate
	output.Duration = overtimeInfo.Duration
	output.CreateAt = overtimeInfo.CreateAt
	output.ApproveAt = overtimeInfo.ApproveAt
	output.Type = overtimeInfo.Type                   //类型 0、不限、1工作日、2周末、3法定假日、4其它
	output.Status = overtimeInfo.Status               //0:draft，1：send；2：delete；3:recall，4:refuse
	output.Note = overtimeInfo.Note                   //备注
	output.ApplicantName = overtimeInfo.ApplicantName //申请人姓名
	output.ApproverName = overtimeInfo.ApproverName   //审批人姓名
	output.DeptName = overtimeInfo.DeptName           //部门名称	employee.id
	output.DurationDay = overtimeInfo.DurationDay     // 时长（天，0.5起跳）
	output.ApplyType = overtimeInfo.ApplyType         //类型 0、不限、1工作日、2周末、3法定假日、4其它
	output.ApplyStatus = overtimeInfo.ApplyStatus     //0:draft，1：send；2：delete；3:recall，4:refuse

	c.JSON(http.StatusOK, model.SuccessObject("操作成功", output))
	global.Log.Info("QueryOvertimeDetail success.", zap.Any("overtime", overtimeInfo))
}

//********************************************
//Func  ：添加新加班
//Method：POST
//Usage ：
//********************************************
func AddNewOvertime(c *gin.Context) {

	//todo. 此处需要判别当前请求发起者身份，仅外包员工才能操作权限
	requester := c.MustGet("USER").(*entity.Employee) //请求人
	if requester.Role != entity.EEmployeeRole_Outsourcing {
		global.Log.Error("AddNewOvertime role error.", zap.Any("requester", requester))
		c.JSON(http.StatusOK, model.Fail("暂不支持非外包员工申请加班"))
		return
	}

	var overtime entity.Overtime
	var err error

	overtime.ApplicantId, err = strconv.ParseInt(c.DefaultPostForm("applicantId", ""), 10, 64)
	if err != nil {
		global.Log.Error("AddNewOvertime applicant id is missing.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("未指明申请人"))
		return
	}
	overtime.DeptId, err = strconv.ParseInt(c.DefaultPostForm("deptId", ""), 10, 64)
	overtime.Reason = c.DefaultPostForm("reason", "")

	startDateStr := c.DefaultPostForm("startDate", "")
	endDateStr := c.DefaultPostForm("endDate", "")
	if startDateStr == "" || endDateStr == "" {
		global.Log.Error("AddNewOvertime startDate and endDate cannot be none.")
		c.JSON(http.StatusOK, model.Fail("加班开始和结束时间必须明确"))
		return
	}

	dtLayout := "2006-01-02 15:04:05"
	loc := db.TZLocation()
	overtime.StartDate, err = time.ParseInLocation(dtLayout, startDateStr, loc)
	if err != nil {
		global.Log.Error("AddNewOvertime startDate convert failed.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("加班开始时间解析不正确"))
		return
	}
	overtime.EndDate, err = time.ParseInLocation(dtLayout, endDateStr, loc)
	if err != nil {
		global.Log.Error("AddNewOvertime endDate convert failed.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("加班结束时间解析不正确"))
		return
	}

	duration, err := strconv.ParseFloat(c.DefaultPostForm("duration", ""), 32)
	if err == nil {
		overtime.Duration = float32(duration)
	} else {
		overtime.Duration = DurationCalc(overtime.StartDate, overtime.EndDate)
		if overtime.Duration <= 0 {
			global.Log.Error("AddNewOvertime duration must >0.", zap.Any("error", err))
			c.JSON(http.StatusOK, model.Fail("加班结束时间须晚于开始时间"))
			return
		}
	}

	newer, err := dao.InsertOvertime(overtime)
	if err != nil {
		global.Log.Error("AddNewOvertime failed.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("添加部门失败"))
	} else {
		var output entity.OutputOvertimeInfo
		output.Id = strconv.FormatInt(newer.Id, 10)
		output.ApplicantId = strconv.FormatInt(newer.ApplicantId, 10)
		output.ApproverId = strconv.FormatInt(newer.ApproverId, 10) //审批人ID
		output.DeptId = strconv.FormatInt(newer.DeptId, 10)         //部门ID
		output.Reason = newer.Reason
		output.StartDate = newer.StartDate
		output.EndDate = newer.EndDate
		output.Duration = newer.Duration
		output.CreateAt = newer.CreateAt
		output.ApproveAt = newer.ApproveAt
		output.Type = newer.Type     //类型 0、不限、1工作日、2周末、3法定假日、4其它
		output.Status = newer.Status //0:draft，1：send；2：delete；3:recall，4:refuse
		output.Note = newer.Note     //备注
		//	output.ApplicantName = newer.ApplicantName                  //申请人姓名
		//	output.ApproverName = overtimeInfo.ApproverName             //审批人姓名
		//	output.DeptName = overtimeInfo.DeptName                     //部门名称	employee.id
		output.DurationDay = overtime.Duration                      // 时长（天，0.5起跳）
		output.ApplyType = dao.OvertimeTypeString(newer.Type)       //类型 0、不限、1工作日、2周末、3法定假日、4其它
		output.ApplyStatus = dao.OvertimeStatusString(newer.Status) //0:draft，1：send；2：delete；3:recall，4:refuse

		c.JSON(http.StatusOK, model.SuccessObject("操作成功", output))
		global.Log.Info("AddNewOvertime success.", zap.Any("new", newer))

		var op entity.OperatingRecord
		op.EmployeeId = overtime.ApplicantId
		op.Event = "新增加班申请 [status:" + strconv.Itoa(overtime.Status) + "] 部门:" + fmt.Sprint(overtime.DeptId)
		dao.InsertOpRecord(op)
	}
}

//********************************************
//Func  ：审批加班申请（通过或拒绝）
//Method：POST
//Usage ：
//Param: overtimeId、approverId、status
//********************************************
func OvertimeApprove(c *gin.Context) {

	//todo .此处需要判别当前请求发起者身份，如果非主管和Hr，则驳回，无此操作权限
	requester := c.MustGet("USER").(*entity.Employee) //请求人
	if requester.Role != entity.EEmployeeRole_DeptLeader && requester.Role != entity.EEmployeeRole_Hr {
		global.Log.Error("OvertimeApprove role error.")
		c.JSON(http.StatusOK, model.Fail("HR或部门主管审批加班"))
		return
	}

	var overtime entity.Overtime
	var err error
	overtime.Id, err = strconv.ParseInt(c.DefaultPostForm("overtimeId", ""), 10, 64)
	if err != nil {
		global.Log.Error("OvertimeApprove overtime is lost.")
		c.JSON(http.StatusOK, model.Fail("未指明加班申请ID"))
		return
	}

	p, err := dao.QueryOvertimeDetail(overtime.Id)
	overtime = *p

	overtime.ApproverId, err = strconv.ParseInt(c.DefaultPostForm("approverId", ""), 10, 64)
	overtime.ApproveAt = time.Now()

	overtime.Status, err = strconv.Atoi(c.DefaultPostForm("status", ""))
	if err != nil {
		global.Log.Error("OvertimeApprove status is error.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("未指明加班审批状态"))
		return
	}
	overtime.Note = c.DefaultPostForm("note", "")
	err = dao.UpdateOvertime(overtime, "status,approve_at,note,approver_id")
	if err != nil {
		global.Log.Error("UpdateDepartment failed.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("更新部门失败"))
	} else {

		type Result struct {
			OvertimeId  string
			ApplicantId string //申请人
			ApproverId  string //审批人
			DeptId      string //部门名称	employee.id
			Type        int
			Status      int
			DurationDay float32 // 时长（天，0.5起跳）
			ApplyType   string  //类型 0、不限、1病假、2事假、3年假、4婚假、5丧家、6其它
			ApplyStatus string  //0:draft，1：send；2：delete；3:recall，4:refuse
			Note        string
		}
		result := &Result{
			OvertimeId:  strconv.FormatInt(overtime.Id, 10),
			ApplicantId: strconv.FormatInt(overtime.ApplicantId, 10),
			ApproverId:  strconv.FormatInt(overtime.ApproverId, 10),
			DeptId:      strconv.FormatInt(overtime.DeptId, 10),
			Type:        overtime.Type,
			Status:      overtime.Status,
			ApplyType:   dao.OvertimeTypeString(overtime.Type),
			ApplyStatus: dao.OvertimeStatusString(overtime.Status),
			Note:        overtime.Note,
		}

		c.JSON(http.StatusOK, model.SuccessObject("操作成功", result))
		global.Log.Info("UpdateDepartment success.", zap.Any("result", result))

		var op entity.OperatingRecord
		op.EmployeeId = overtime.ApplicantId
		op.Event = "加班申请审批 [status:" + strconv.Itoa(overtime.Status) + "] 审批人:" + fmt.Sprint(overtime.ApproverId)
		dao.InsertOpRecord(op)
	}
}

//********************************************
//Func  ：批量审批加班申请（通过或拒绝）
//Method：POST
//Usage ：
//Param: overtimeId、approverId、status
//********************************************
func OvertimeApproveBatch(c *gin.Context) {

	//todo .此处需要判别当前请求发起者身份，如果非主管和Hr，则驳回，无此操作权限
	requester := c.MustGet("USER").(*entity.Employee) //请求人
	if requester.Role != entity.EEmployeeRole_DeptLeader && requester.Role != entity.EEmployeeRole_Hr {
		global.Log.Error("OvertimeApproveBatch role error.")
		c.JSON(http.StatusOK, model.Fail("HR或部门主管审批请假"))
		return
	}

	var overtimeList []entity.Overtime
	var err error

	// todo 这里要获取审批者的id，并判断权限
	approverId := int64(0)

	idListStr := c.DefaultPostForm("overtimeIdList", "")
	if len(idListStr) <= 0 {
		global.Log.Error("OvertimeApproveBatch overtime is lost.")
		c.JSON(http.StatusOK, model.Fail("未指明请假申请ID"))
		return
	}
	status, err := strconv.Atoi(c.DefaultPostForm("status", ""))
	if err != nil {
		global.Log.Error("OvertimeApproveBatch status is error.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("未指明请假审批状态"))
		return
	}
	note := c.DefaultPostForm("note", "")

	idList := strings.Split(idListStr, ",")
	for _, idStr := range idList {
		var overtime entity.Overtime
		overtime.Id, err = strconv.ParseInt(idStr, 10, 64)
		if err != nil {
			global.Log.Error("OvertimeApproveBatch parse app id failed.", zap.Any("error", err))
			c.JSON(http.StatusOK, model.Fail("批量申请解析异常"))
			return
		}
		overtime.ApproveAt = time.Now()
		overtime.ApproverId = approverId
		overtime.Status = status
		overtime.Note = note
		overtimeList = append(overtimeList, overtime)
	}

	err = dao.UpdateOvertimeBatch(overtimeList, "status,approve_at,note,approver_id")
	if err != nil {
		global.Log.Error("OvertimeApproveBatch failed.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("批量审批失败"))
	} else {
		c.JSON(http.StatusOK, model.SuccessObject("操作成功", idList))
		global.Log.Info("OvertimeApproveBatch success.", zap.Any("approve batch", idList))

		var op entity.OperatingRecord
		op.EmployeeId = 0
		op.Event = "加班申请批量审批 [status:" + strconv.Itoa(status) + "] 审批人:" + fmt.Sprint(approverId)
		dao.InsertOpRecord(op)
	}
}

//********************************************
//Func  ：召回任务或取消任务
//Method：POST
//Usage ：
//********************************************
func OvertimeCancelOrRecall(c *gin.Context) {

	var overtime entity.Overtime
	var err error
	overtime.Id, err = strconv.ParseInt(c.DefaultPostForm("overtimeId", ""), 10, 64)
	if err != nil {
		global.Log.Error("OvertimeApprove overtime is lost.")
		c.JSON(http.StatusOK, model.Fail("未指明加班申请ID"))
		return
	}

	overtimeInfo, err := dao.QueryOvertimeInfo(overtime.Id)
	if overtimeInfo.Status == entity.EOvertimeStatus_Recall ||
		overtimeInfo.Status == entity.EOvertimeStatus_PassAndCancel ||
		overtimeInfo.Status == entity.EOvertimeStatus_Delete {

		global.Log.Error("OvertimeApprove status has cancle.")
		c.JSON(http.StatusOK, model.Fail("请假申请不能重复撤销"))
		return
	}

	status, err := strconv.Atoi(c.DefaultPostForm("status", ""))
	if err != nil {
		global.Log.Info("OvertimeApprove status is missing.", zap.Any("error", err))
		if overtime.Status == entity.EOvertimeStatus_Pass {
			overtime.Status = entity.EOvertimeStatus_PassAndCancel
			overtimeInfo.Status = entity.EVacationStatus_PassAndCancel
		} else {
			overtime.Status = entity.EOvertimeStatus_Recall
			overtimeInfo.Status = entity.EOvertimeStatus_Recall
		}
	} else {
		overtime.Status = status
		overtimeInfo.Status = status
	}

	note := c.DefaultPostForm("note", "")
	if len(note) > 0 {
		overtime.Note += ("\n" + note) //合并批注信息内容
		overtimeInfo.Note += ("\n" + note)
	}

	err = dao.UpdateOvertime(overtime, "status,note")
	if err != nil {
		global.Log.Error("UpdateDepartment failed.", zap.Any("error", err))
		c.JSON(http.StatusOK, model.Fail("更新部门失败"))
	} else {
		output := &entity.OutputOvertimeInfo{
			Id:            strconv.FormatInt(overtime.Id, 10),
			ApplicantId:   strconv.FormatInt(overtime.ApplicantId, 10),
			ApproverId:    strconv.FormatInt(overtime.ApproverId, 10), //审批人ID
			DeptId:        strconv.FormatInt(overtime.DeptId, 10),     //部门ID
			Reason:        overtime.Reason,
			StartDate:     overtime.StartDate,
			EndDate:       overtime.EndDate,
			Duration:      overtime.Duration,
			CreateAt:      overtime.CreateAt,
			ApproveAt:     overtime.ApproveAt,
			Type:          overtime.Type,              //类型 0、不限、1工作日、2周末、3法定假日、4其它
			Status:        overtime.Status,            //0:draft，1：send；2：delete；3:recall，4:refuse
			Note:          overtime.Note,              //备注
			ApplicantName: overtimeInfo.ApplicantName, //申请人姓名
			ApproverName:  overtimeInfo.ApproverName,  //审批人姓名
			DeptName:      overtimeInfo.DeptName,      //部门名称	employee.id
			DurationDay:   overtimeInfo.DurationDay,   // 时长（天，0.5起跳）
			ApplyType:     overtimeInfo.ApplyType,     //类型 0、不限、1工作日、2周末、3法定假日、4其它
			ApplyStatus:   overtimeInfo.ApplyStatus,   //0:draft，1：send；2：delete；3:recall，4:refuse
		}

		c.JSON(http.StatusOK, model.SuccessObject("操作成功", output))
		global.Log.Info("UpdateDepartment success.", zap.Any("update overtime", overtime))

		var op entity.OperatingRecord
		op.EmployeeId = overtime.ApplicantId
		op.Event = "取消加班申请 [status:" + strconv.Itoa(overtime.Status) + "]"
		dao.InsertOpRecord(op)
	}

}

//********************************************
//Func  ：查询加班类型
//Method：GET
//Usage ：下拉选择加班类型
//********************************************
func QueryOvertimeTypes(c *gin.Context) {
	type OvertimeType struct {
		Id   int
		Type string
	}
	types := []*OvertimeType{}
	type1 := &OvertimeType{
		Id:   entity.EOvertimeType_Workday,
		Type: "工作日加班",
	}
	types = append(types, type1)

	type2 := &OvertimeType{
		Id:   entity.EOvertimeType_Weekend,
		Type: "周末加班",
	}
	types = append(types, type2)

	type3 := &OvertimeType{
		Id:   entity.EOvertimeType_OfficialHoliday,
		Type: "法定假日加班",
	}
	types = append(types, type3)
	type6 := &OvertimeType{
		Id:   entity.EOvertimeType_Other,
		Type: "其他",
	}
	types = append(types, type6)
	c.JSON(http.StatusOK, model.SuccessObject("操作成功", types))
}

//********************************************
//Func  ：查询状态类型
//Method：GET
//Usage ：状态类型类型
//********************************************
func QueryStatusTypes(c *gin.Context) {
	type StatusType struct {
		Id   int
		Type string
	}

	types := []*StatusType{}
	type0 := &StatusType{
		Id:   entity.EVacationStatus_Draft,
		Type: "草稿",
	}
	types = append(types, type0)

	type1 := &StatusType{
		Id:   entity.EVacationStatus_Send,
		Type: "待审批",
	}
	types = append(types, type1)

	type2 := &StatusType{
		Id:   entity.EVacationStatus_Delete,
		Type: "删除",
	}
	types = append(types, type2)

	type3 := &StatusType{
		Id:   entity.EVacationStatus_Recall,
		Type: "召回",
	}
	types = append(types, type3)

	type4 := &StatusType{
		Id:   entity.EVacationStatus_Refuse,
		Type: "拒绝",
	}
	types = append(types, type4)

	type5 := &StatusType{
		Id:   entity.EVacationStatus_PassAndCancel,
		Type: "通过后取消",
	}
	types = append(types, type5)

	type6 := &StatusType{
		Id:   entity.EVacationStatus_Pass,
		Type: "通过审批",
	}
	types = append(types, type6)

	c.JSON(http.StatusOK, model.SuccessObject("操作成功", types))
}

//又开始时间和结束时间计算，0.5天未步进单位
func DurationCalc(startDate, endDate time.Time) float32 {
	//加班开始时间
	duration := endDate.Sub(startDate)
	if duration <= 0 {
		return float32(duration)
	}
	var sum float32 = 0.0

	if startDate.Year() == endDate.Year() &&
		startDate.Month() == endDate.Month() &&
		startDate.Day() == endDate.Day() { //同一天里
		if startDate.Hour() < 12 {
			sum += 0.5
		}
		if endDate.Hour() > 13 {
			sum += 0.5
		}
		return sum
	}

	for currentDate := startDate; ; {
		if currentDate.After(endDate) {
			break
		}
		if currentDate == startDate {
			//第一天
			if currentDate.Hour() < 12 {
				sum += 1
			} else {
				sum += 0.5
			}
			currentDate = currentDate.AddDate(0, 0, 1) //向后加一天
			continue
		}
		if currentDate.Year() == endDate.Year() &&
			currentDate.Month() == endDate.Month() &&
			currentDate.Day() == endDate.Day() { //最后一天里
			if endDate.Hour() < 12 {
				sum += 0.5 //半天
			} else {
				sum += 1.0 //全天
			}
			break
		}

		currentDate = currentDate.AddDate(0, 0, 1) //向后加一天
		sum += 1.0
	}
	fmt.Println(sum)
	//	EndDate     time.Time 						//加班终止时间
	return sum
}
